from .utils import Methods, RouteRule


class Router:

    # 顶级路由的集合
    METHODS = Methods(*[[] for _ in range(Methods.length)])

    # 放所有的子视图函数的代理router，将路由分级筛选后在进行匹配，提升效率
    ROUTERS = {}

    def __init__(self, url_prefix=""):
        if not url_prefix.startswith("/"):
            raise ValueError("must be startswith '/' !")

        self._url_prefix = url_prefix

        # 代理为url_prefix，使用左前缀进行完全匹配
        self.ROUTERS[url_prefix] = Methods(*[[] for _ in range(Methods.length)])

    # register function
    def route(self, path, methods="GET POST"):
        if isinstance(methods, str):
            methods = list(map(lambda x: x.upper(), methods.split()))

        def _route(fn):
            route_rule = RouteRule(path, methods, fn)

            for method in methods:

                # 程序员写路由的时候该方法框架不支持时，只能注册到GET方法集合里
                # 从self.ROUTERS这个包含所有的url_prefix的字典代理中，根据当前的url_prefix代理，找出那个对象
                # 那个对象是一个Methods对象，内部有几个属性，每个属性对应一个列表，将不同的匹配规则放到不同方法的列表中，
                # 分流图为    ↓↓↓↓↓↓↓↓↓    是一个三级模型，先根据url_prefix进行第一级的筛选，然后根据此代理的方法不同进行第二级筛选
                #                         最后再根据路径进行第三级的筛选，希望能效率略高一些，当我们的视图函数更厚重的时候，可能会有问题
                # url_prefix
                #         method
                #             path

                rule_list: list = getattr(self.ROUTERS.get(self._url_prefix), method)
                rule_list.append(route_rule)
                # self.Router.route_rule_list.append(route_rule)

        return _route

    def get(self, path):
        return self.route(path, methods="GET")

    def post(self, path):
        return self.route(path, methods="POST")

    def show(self):
        print(self.ROUTERS)

    def get_sub_router(self, url_prefix="/"):
        if not url_prefix.startswith("/"):
            raise ValueError("must be startswith '/' !")
        return Router(self._url_prefix + url_prefix)
